home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 318_01 / redsys.c < prev   
C/C++ Source or Header  |  1990-06-16  |  14KB  |  756 lines

  1. /*
  2.     RED operating system module -- Full C version
  3.  
  4.     Source:  redsys.c
  5.     Version: June 18, 1986; January 18, 1990.
  6.  
  7.     Written by
  8.     
  9.         Edward K. Ream
  10.         166 N. Prospect
  11.         Madison WI 53705
  12.         (608) 257-0802
  13.  
  14.  
  15.     PUBLIC DOMAIN SOFTWARE
  16.  
  17.     This software is in the public domain.
  18.  
  19.     See red.h for a disclaimer of warranties and other information.
  20. */
  21.  
  22. #include "red.h"
  23.  
  24. #ifdef MICRO_SOFT
  25. #include <bios.h>
  26. #include <fcntl.h>
  27. #include <io.h>
  28. #include <malloc.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <sys\types.h>
  33. #include <sys\stat.h>
  34. #endif
  35.  
  36. #ifdef TURBOC
  37. #include <alloc.h>
  38. #include <conio.h>
  39. #include <fcntl.h>
  40. #include <io.h>
  41. #include <mem.h>
  42. #include <sys\stat.h>
  43. #endif
  44.  
  45. static char sysinbuf[128];        /* file buffer        */
  46. static int  sysincnt;            /* index to sysinbuf[]    */
  47. static char syscbuf[MAXLEN];        /* typeahead buffer    */
  48. static int  sysccnt;            /* index for syscbuf[]    */
  49. static int  sysrcnt;            /* repeat count        */
  50. static int  syslastc;            /* last character    */
  51. static int  systopl,systopy,sysnl;    /* interrupt info    */
  52.  
  53. /*
  54.     NOTE:  This module should contain all routines that
  55.     might have to be changed for different compilers or
  56.     different operating systems.  
  57.  
  58.     Some routines in this module probably will probably
  59.     work regardless of operating system.  These I have
  60.     called PORTABLE routines.
  61. */
  62.  
  63. /*
  64.     Return a pointer to a block of n contiguous bytes.
  65.     Return NULL (i.e.,  0) if fewer than n bytes remain.
  66. */
  67. char *
  68. sysalloc(n)
  69. int n;
  70. {
  71.     char * p;
  72.     p = (char *) malloc(n);
  73.  
  74.     TRACEP("sysalloc",
  75.         sl_lpout(); sl_iout(n);
  76.         sl_sout(") returns "); sl_pout(p); sl_cout('\n'));
  77.  
  78.     return p;
  79. }
  80.  
  81. /*
  82.     o  Wait for next character from the console.
  83.     o  Do NOT echo the character.
  84.     o  Print any waiting lines if there is no input ready.
  85.         o  Swap out any dirty blocks if nothing else is happening.
  86.        (The SWAP constant enables this feature)
  87. */
  88. int
  89. syscin(void)
  90. {
  91.     int c;
  92.     int main_byte, aux_byte;
  93.  
  94.     SL_DISABLE();
  95.  
  96.     for(;;) {
  97.         c = syscstat();
  98.         if (c != -1) {
  99.             break;
  100.         }
  101.  
  102.         /* Output queued ? */
  103.         if (hasint && sysnl > 0) {
  104.             /* Print one line. */
  105.             bufout(systopl, systopy, sysnl);
  106.         }
  107.  
  108. #ifdef SWAP
  109.         /* Do not interrupt screen activity. */
  110.         if (sysnl == 0) {
  111.             /* Swap out one dirty buffer. */
  112.             swap_one();
  113.         }
  114. #endif
  115.  
  116.     }
  117.  
  118. #ifdef IBM
  119.  
  120.     main_byte = c & 0xff;
  121.     aux_byte  = (c & 0xff00) >> 8;
  122.  
  123.     TRACEP("syscin",
  124.         sl_sout(" main: "); sl_iout(main_byte);
  125.         sl_sout(" aux: ");  sl_iout(aux_byte);
  126.         sl_cout('\n'));
  127.  
  128.     /* Handle cursor keys and the numeric keypad. */
  129.     if (main_byte == 0) switch (aux_byte) {
  130.  
  131.         case 71: return HOME_KEY;     /* Home key.     */
  132.         case 79: return END_KEY;     /* End key.       */
  133.  
  134.         case 73: return PAGE_UP;    /* Page up key.   */
  135.         case 81: return PAGE_DN;    /* Page down key. */
  136.         case 82: return UP_INS;        /* Insert key     */
  137.         case 83: return DEL2;        /* Delete Key     */
  138.  
  139.         case 77:  return RIGHT;        /* Arrow keys.    */
  140.         case 75:  return LEFT;
  141.         case 72:  return UP;
  142.         case 80:  return DOWN;
  143.     }
  144.  
  145. #endif
  146.  
  147.     return c & 0x7f;
  148. }
  149.  
  150. /*
  151.     Close an unbuffered file.
  152.     Return OK (0) or ERROR (-1).
  153. */
  154. int
  155. sysclose(int fd)
  156. {
  157.     TRACEP("sysclose", sl_lpout(); sl_iout(fd); sl_rpout());
  158.  
  159.     close(fd);
  160. }
  161.  
  162. /*
  163.     Copy a file name from args to buffer.
  164.     This routine is SEMI-PORTABLE,  since it depends,
  165.     to a certain extent,  on what constitutes a file name.
  166. */
  167. void
  168. syscopfn(char *args, char *buffer)
  169. {
  170.     int n;
  171.  
  172.     TRACEP("syscopfn",       sl_lpout();
  173.         sl_sout(args);   sl_csout();
  174.         sl_pout(buffer); sl_rpout());
  175.  
  176.     for (n = 0;
  177.          n < SYSFNMAX -1 && args [n] != '\0' && args [n] != ' ';
  178.          n++) {
  179.  
  180.         buffer [n] = args [n];
  181.     }
  182.     buffer[n] = '\0';
  183. }
  184.  
  185. /*
  186.     Create an file for use by sysread and syswrite.
  187.     Erase it if it exists and leave it open for read/write access.
  188.     Return a small positive int or ERROR  (-1).
  189. */
  190. int
  191. syscreat(char * filename)
  192. {
  193.     int result;
  194.  
  195.     TRACEP("syscreat", sl_lpout(); sl_sout(filename));
  196.  
  197. #ifdef MICRO_SOFT
  198.     _fmode = O_BINARY;
  199.     result = creat(filename, S_IREAD | S_IWRITE);
  200.     _fmode = O_TEXT;
  201. #endif
  202.  
  203. #ifdef TURBOC
  204.     _fmode = O_BINARY;
  205.     result = creat(filename, S_IREAD | S_IWRITE);
  206.     _fmode = O_TEXT;
  207. #endif
  208.  
  209.     TRACE("syscreat",
  210.         sl_sout(") returns "); sl_iout(result); sl_cout('\n'));
  211.  
  212.     return result;
  213. }
  214.  
  215. /*
  216.     Return -1 if no character is ready from the keyboard.
  217.     Otherwise, return the character itself.
  218.  
  219.     This routine handles typeahead buffering.  It would
  220.     also handle the repeat key,  if that feature is used,
  221.     which it is NOT at present.  The code enclosed in
  222.     comments handles the repeat key.
  223. */
  224. int
  225. syscstat(void)
  226. {
  227.     int c;
  228.  
  229.     SL_DISABLE();
  230.  
  231.     /* Always look for another character. */
  232.  
  233. #ifdef MICRO_SOFT
  234.  
  235.     c = _bios_keybrd(_KEYBRD_READY);
  236.     if (c == 0) {
  237.         c = -1;
  238.     }
  239.     else {
  240.         _bios_keybrd(_KEYBRD_READ);
  241.     }
  242. #endif
  243.  
  244. #ifdef TURBOC
  245.  
  246.     c = bioskey(1);
  247.     if (c == 0) {
  248.         c = -1;
  249.     }
  250.     else {
  251.         bioskey(0);
  252.     }
  253. #endif
  254.  
  255.     return c;
  256. }
  257.  
  258.  
  259. /*
  260.     Execute args as if they were entered from the command line.
  261. */
  262. void
  263. sysexec(char *args)
  264. {
  265.  
  266.     SL_DISABLE();
  267.  
  268. #ifdef MICRO_SOFT
  269.     system(args);
  270.     puts("\nPress any key to resume editing: ");
  271.     syscin();
  272. #endif
  273.  
  274. #ifdef TURBOC
  275.     system(args);
  276.     puts("\nPress any key to resume editing: ");
  277.     syscin();
  278. #endif
  279.  
  280. }
  281.  
  282. /*
  283.     Return TRUE if the file exists and FALSE otherwise.
  284.     This routine is PORTABLE.
  285. */
  286. int
  287. sysexists(char * filename)
  288. {
  289.     int fd;
  290.  
  291.     TRACEPB("sysexists", sl_lpout(); sl_sout(filename); sl_rpout());
  292.  
  293.     if ((fd = sysopen(filename)) != ERROR) {
  294.         sysclose(fd);
  295.  
  296.         RETURN_BOOL("sysexists", TRUE);
  297.     }
  298.     else {
  299.         RETURN_BOOL("sysexists", FALSE);
  300.     }
  301. }
  302.  
  303. /*
  304.     Close and flush a file opened with sysfopen or sysfcreat.
  305.     Return OK (0) or ERROR (-1).
  306. */
  307. int
  308. sysfclose(FILE *fd)
  309. {
  310.     TRACEP("sysfclose", sl_lpout(); sl_pout(fd); sl_rpout());
  311.  
  312.     return fclose(fd);
  313. }
  314.  
  315. /*
  316.     Create a buffered output file for use with sysfputs.
  317.  
  318.     The file is cleared (erased) if it already exists.
  319.     A pointer to FILE is returned if all goes well.
  320.     NULL (0), is returned if the file can not be created.
  321. */
  322. FILE *
  323. sysfcreat(char *filename)
  324. {
  325.     FILE * f;
  326.  
  327.     TRACEP("sysfcreat", sl_lpout();    sl_sout(filename));
  328.  
  329. #ifdef MICRO_SOFT
  330.     f = fopen(filename, "w");
  331. #endif
  332.  
  333. #ifdef TURBOC
  334.     f = fopen(filename, "w");
  335. #endif
  336.  
  337.     TRACE("sysfcreat",
  338.         sl_sout(") returns "); sl_pout(f); sl_cout('\n'));
  339.  
  340.     return f;
  341. }
  342.  
  343. /*
  344.     Read the next line from buffered input file.
  345.     End the line with an '\n'.
  346.     Return the count of the characters read.
  347.     Return ERROR (-1) on end-of-file.
  348. */
  349. int
  350. sysfgets(FILE *fd, char *buffer, int maxlen)
  351. {
  352.     int c, count;
  353.  
  354.     TRACEP("sysfgets",      sl_lpout();
  355.         sl_pout(fd);     sl_csout();
  356.         sl_pout(buffer); sl_csout(); 
  357.         sl_iout(maxlen));
  358.  
  359.     count = 0;
  360.     while(1) {
  361.         c = sysgetc(fd);
  362.         if (c == '\r') {
  363.             /* Ignore pseudo newline. */
  364.             continue;
  365.         }
  366.         else if (c == EOF_MARK || c == ERROR) {
  367.             buffer [min(count, maxlen-2)] = '\n';
  368.             buffer [min(count, maxlen-1)] = '\0';
  369.  
  370.             TRACE("sysfgets", sl_sout(") returns ERROR\n"));
  371.             return ERROR;
  372.         }
  373.         else if (c == '\n') {
  374.             buffer [min(count, maxlen-2)] = '\n';
  375.             buffer [min(count, maxlen-1)] = '\0';
  376.             TRACE("sysfgets",
  377.                 sl_sout(") returns ");
  378.                 sl_iout(count);
  379.                 sl_cout('\n'));
  380.             return count;
  381.         }
  382.         else if (count < maxlen - 2) {
  383.             buffer [count++] = c;
  384.         }
  385.         else {
  386.             count++;
  387.         }
  388.     }
  389. }
  390.  
  391. /*
  392.     Write n BYTES from the buffer to the END of an unbuffered file.
  393.     Return ERROR (-1) or 1.
  394. */
  395. int
  396. sysflush(int fd, char * buffer, int n)
  397. {
  398.     int result;
  399.  
  400. #ifdef MICRO_SOFT
  401.     result = (write(fd, buffer, n) == -1) ? ERROR : 1;
  402. #endif
  403.  
  404. #ifdef TURBOC
  405.     result = (write(fd, buffer, n) == -1) ? ERROR : 1;
  406. #endif
  407.  
  408.     return result;
  409.  
  410. }
  411.  
  412. /*
  413.     Open a buffered input file for use by sysfgets and sysgetc.
  414.  
  415.     Return FILE or NULL if the file does not exist.
  416. */
  417. FILE *
  418. sysfopen(char *filename)
  419. {
  420.     FILE * f;
  421.  
  422. #ifdef MICRO_SOFT
  423.     f = fopen(filename, "r");
  424. #endif
  425.  
  426. #ifdef TURBOC
  427.     f = fopen(filename, "r");
  428. #endif
  429.  
  430.     return f;
  431. }
  432.  
  433. /*
  434.     Get the next characer from a file opened by sysfopen.